library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity BRANCH is
	Port ( clkin : in STD_LOGIC;
			v : in STD_LOGIC_VECTOR (15 downto 0);
			vin : in STD_LOGIC;
			vack : out STD_LOGIC;
			t : out STD_LOGIC_VECTOR (15 downto 0);
			tstr : out STD_LOGIC;
			tack : in STD_LOGIC;
			f : out STD_LOGIC_VECTOR (15 downto 0);
			fstr : out STD_LOGIC;
			fack : in STD_LOGIC;
			c : in STD_LOGIC;
			cin : in STD_LOGIC;
			cack : out STD_LOGIC);
end BRANCH;

architecture Behavioral of BRANCH is
	type estados is(ramificar, enviot, enviof);
	begin
		dados: 	process(clkin, vin, tack, fack, cin)
				variable estado: estados := ramificar;
				variable recv: STD_LOGIC := '0';
				variable recc: STD_LOGIC := '0';
				variable vd: STD_LOGIC_VECTOR(15 downto 0);
				variable tdt: STD_LOGIC_VECTOR(15 downto 0);
				variable fdt: STD_LOGIC_VECTOR(15 downto 0);
				variable cd: STD_LOGIC;
		begin
			if clkin'event and clkin = '1' then
				t <= "ZZZZZZZZZZZZZZZZ";
				f <= "ZZZZZZZZZZZZZZZZ";
				tstr <= '0';
				fstr <= '0';
				vack <= '0';
				cack <= '0';
				case estado is
					when ramificar =>
						if vin = '1' then
							vd := v;
							vack <= '1';
							recv := '1';
						end if;
						if cin = '1' then
							cd := c;
							cack <= '1';
							recc := '1';
						end if;
						if recv = '1' and recc = '1' then
							if cd = '1' then
								tdt := vd;
								estado := enviot;
							else
								fdt := vd;
								estado := enviof;
							end if;
							recv := '0';
							recc := '0';
						end if;
					when enviot =>
						if tack = '1' then
							estado := ramificar;
						else
							t <= tdt;
							tstr <= '1';
						end if;
					when enviof =>
						if fack = '1' then
							estado := ramificar;
						else
							f <= fdt;
							fstr <= '1';
						end if;
				end case;
			end if;
	end process dados;
end Behavioral;